#include <physical_mm.h>
#include <sys/types.h>
#include <debug.h>


extern "C" {
	// global objects
	int __cxa_atexit(void (*f)(void *), void *p, void *d);
    void __cxa_finalize(void *d);
    // pure virtual functions
    void __cxa_pure_virtual();
};

/*
 *  Global objects
 */
void *__dso_handle; /*only the address of this symbol is taken by gcc*/

struct object {
        void (*f)(void*);
        void *p;
        void *d;
} object[32] = {{0}};

uint_t iObject = 0;

int __cxa_atexit(void (*f)(void *), void *p, void *d) {
        if (iObject >= 32) return -1;
        object[iObject].f = f;
        object[iObject].p = p;
        object[iObject].d = d;
        ++iObject;
        return 0;
}

/* This currently destroys all objects */
void __cxa_finalize(void *d) {
        uint_t i = iObject;
        for (; i > 0; --i) {
                --iObject;
                object[iObject].f(object[iObject].p);
        }
}

/*
 * Pure virtual function - it'll be called if a pure virtual function couldn't be made
 */
void __cxa_pure_virtual() {
	// print error message
}


/*
 * Overloads the operator "new" and "delete" operators
 */
void* operator new (uint_t size) {
	Debug::dprint("operators->new");
    return PhysicalMemoryManager::kmalloc(size);
}


void* operator new[] (uint_t size) {
	Debug::dprint("operators->new[]");
    return PhysicalMemoryManager::kmalloc(size);
}

void operator delete (void * p) {
	Debug::dprint("operators->delete");
	PhysicalMemoryManager::kfree( p );
}

void operator delete[] (void * p) {
	Debug::dprint("operators->delete[]");
	PhysicalMemoryManager::kfree( p );
}
